﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MicropleSoft.WmsApp.Library.ClientProxy;
using MicropleSoft.WmsApp.Library.ServiceFacade;

namespace MicropleSoft.WmsApp.Library.Proxy
{
    public  class ServerProxy
    {
        private static readonly IServiceFacadeChannel ServiceFacadeClientInstance =
            ClientProxyFactory.GetServiceFacadeClient();
        private static readonly Type TypeInstance = typeof(IServiceFacadeChannel);
        private const string ServiceInterfaceName = "IServiceFacade";
        static ServerProxy()
        {
           
        }

        public T Query<T>(string functionName, params object[] parameters)
            where T : IBaseDomainObject
        {
            var domainObject =(T)TypeInstance.GetInterface(ServiceInterfaceName).GetMethod(functionName).Invoke(
                    ServiceFacadeClientInstance, parameters);

            domainObject.AfterQueryFromServer();

            return domainObject;
        }

        public List<T> Query<T>( string functionName,string condition,params object [] parameters)
             where T:IBaseDomainObject
         {
            var newParameters = new object[parameters.Length + 1];
            newParameters[0] = condition;
            for(int idx = 1;idx<newParameters.Length;idx++)
            {
                newParameters[idx] = parameters[idx - 1];
            }
            var list = (List<T>)TypeInstance.GetInterface(ServiceInterfaceName).GetMethod(functionName).Invoke(ServiceFacadeClientInstance, newParameters);
            foreach (var domainObject in list)
            {
                domainObject.AfterQueryFromServer();
            }
            return list;
         }

        public void Save<T>(string functionName,List<T> list ) 
            where T:IBaseDomainObject
        {
            var tempList = EntityFilterByState.GetNeedSaveEntity(list);
            TypeInstance.GetInterface(ServiceInterfaceName).GetMethod(functionName).Invoke(ServiceFacadeClientInstance, new object[]{tempList});
            foreach (var domainObject in list)
            {
                domainObject.AcceptChanges();
            }
        }

        public void Save<T>(string functionName, List<T> list,List<String> notUpdateProperties)
         where T : IBaseDomainObject
        {
            var tempList = EntityFilterByState.GetNeedSaveEntity(list);
            TypeInstance.GetInterface(ServiceInterfaceName).GetMethod(functionName).Invoke(ServiceFacadeClientInstance, new object[] { tempList, notUpdateProperties });
            foreach (var domainObject in list)
            {
                domainObject.AcceptChanges();
            }
        }

        public void Save<T>(string functionName, T domainObject)
            where T : IBaseDomainObject
        {
            TypeInstance.GetInterface(ServiceInterfaceName).GetMethod(functionName).Invoke(ServiceFacadeClientInstance,
                                                                                           new object[] {domainObject});
            domainObject.AcceptChanges();
        }

        public void Save<T>(string functionName, T domainObject, List<String> notUpdateProperties)
          where T : IBaseDomainObject
        {
            TypeInstance.GetInterface(ServiceInterfaceName).GetMethod(functionName).Invoke(ServiceFacadeClientInstance,
                                                                                           new object[] { domainObject,  notUpdateProperties });
            domainObject.AcceptChanges();
        }

        /// <summary>
        /// 调用此方法返回的Wrap对象一定要注意调用子对象的 domainObject.AcceptChanges();
        /// 否则不会在属性修改是触发事件：修改对象状态。
        /// </summary>
        /// <param name="functionName"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public object CallService(string functionName, params object [] parameters)
        {
            return TypeInstance.GetInterface(ServiceInterfaceName).GetMethod(functionName).
                Invoke(ServiceFacadeClientInstance,parameters );
        }
    }
}
